package com.hisense.proxy.service.entity.output_invoice;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.google.gson.GsonBuilder;
import com.hisense.proxy.busitrans.vo.HxFdcprBusitransApplyInvoiceBodyDetailVO;
import com.hisense.proxy.busitrans.vo.HxFdcprBusitransApplyInvoiceHeadVO;
import com.hisense.proxy.busitrans.vo.RedInvoiceReqProxyVO;

/**
 * @program: yesfp-demo
 * @description: 开票
 * @author: kw
 * @create: 2020/05/21 12:41
 */
@Service
public class InvoiceBuildParam {
	
	public static final Map<String, String> zdybzMap = new HashMap<String, String>();

	@Value("${yesfp.callback.url.root}")
	private String invoiceCallbackRootUrl;

	@Value("${yesfp.callback.url.busitrans.blue}")
	private String blueBusitransInvoiceCallbackApplyUri;
	
	@Value("${yesfp.callback.url.busitrans.red}")
	private String redBusitransInvoiceCallbackApplyUri;
	
	@Value("${yesfp.callback.url.busiapply.blue}")
	private String blueBusiApplyInvoiceCallbackApplyUri;
	
	@Value("${yesfp.callback.url.busiapply.red}")
	private String redBusiApplyInvoiceCallbackApplyUri;

	// 所有商品对应相同的商品编码
	@Value("${yesfp.spbm}")
	private String spbm;

	@Value("${yesfp.env.orgcode}")
	private String configOrgcode;

	/**
	 * 扫码开票 XSF_NSRSBH String 20 是 销售方纳税人识别号 JSHJ Double 15,2 是 价税合计 两位小数 ORGCODE
	 * String 100 是 电子发票平台唯一标识，从电子发票平台获取。 RQSJ String 100 是 日期时间 SHMC String 100 是
	 * 商户名称
	 */
	public static Map<String, Object> scanApply() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("XSF_NSRSBH", "9144011476190205X4");
		paramsMap.put("JSHJ", "15.2");
		paramsMap.put("orgcode", "20160914001");
		paramsMap.put("RQSJ", "2021-01-01");
		paramsMap.put("SHMC", "接口测试wrk");
//        paramsMap.put("items",buildItems());
		paramsMap.put("FPQQLSH", "12345678910aaasssddd");
		paramsMap.put("GMF_MC", "广州佰仕德材料科技有限公司");
		paramsMap.put("GMF_NSRSBH", "91440101MA5CR3FU35");
		paramsMap.put("GMF_DZDH", "广州市花都区红棉大道北16号4楼4B07室 020-61796191");
		paramsMap.put("GMF_YHZH", "中国农业银行股份有限公司广州花都名门支行 44087001040011474");
		return paramsMap;
	}

	/**
	 * 构造获取专票参数
	 */
	public static Map<String, Object> buildQueryInvoiceParam() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("yfpDm", "");
		paramsMap.put("yfpHm", "");
		paramsMap.put("orgcode", "20160914001");
		paramsMap.put("rq_q", "2018-01-01");
		paramsMap.put("rq_z", "2022-05-06");
		paramsMap.put("period", "202002");
		return paramsMap;
	}

	/**
	 * 构造 专票红冲状态查询接口 参数
	 */
	public static Map<String, Object> buildRedStateTotalParam() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("yfpDm", "100000064388");
		paramsMap.put("yfpHm", "55216153");
		return paramsMap;
	}

	/**
	 * 构造 发票作废 表单数据
	 */
	public static Map<String, Object> buildInvalidParam(String fpHm, String fmDm) {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("requestdatas", buildInvalidRequestdatas(fpHm, fmDm));
		return paramsMap;
	}

	/**
	 * 构造 发票打印 表单数据
	 */
	public static Map<String, Object> buildTaxPrintParam() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		// 发票代码
		paramsMap.put("fpDm", "200004275230");
		// 发票号码
		paramsMap.put("fpHm", "23770399");
		paramsMap.put("orgCode", "20160914001");

		return paramsMap;
	}

	/**
	 * 未开票查询
	 */
	public static Map<String, Object> result() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		// 发票代码
		paramsMap.put("lyid", "1");
		// 发票号码
		paramsMap.put("djqqlsh", "23770399");
		paramsMap.put("orgCode", "20160914001");
		paramsMap.put("pageNum", "1");
		paramsMap.put("orgSize", "20160914001");

		return paramsMap;
	}

	/**
	 * 构造 开票状态查询服务 表单数据
	 */
	public static Map<String, String> buildQueryInvoiceStatusPostParam(String fpqqlsh) {
		Map<String, String> paramsMap = new HashMap<String, String>();
		paramsMap.put("fpqqlsh", fpqqlsh);
		return paramsMap;
	}

	/**
	 * 构造 开票申请删除 表单数据
	 */
	public static Map<String, Object> buildInvoiceApplyDelParam() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		List<Object> datas = new ArrayList<>();
		Map<String, String> requestdatas = new HashMap();
		requestdatas.put("FPQQLSH", buildFpqqlsh());
		requestdatas.put("XSF_NSRSBH", "9144011476190205X4");
		datas.add(requestdatas);
		paramsMap.put("requestdatas", new GsonBuilder().create().toJson(datas));
		return paramsMap;
	}

	/**
	 * 构造 开票蓝票请求服务 表单数据
	 */
	public Map<String, String> buildInsertWithArrayPostParam(HxFdcprBusitransApplyInvoiceHeadVO bodyData, boolean isApply) {
		Map<String, String> paramsMap = new HashMap<String, String>();
		paramsMap.put("requestdatas", buildRequestDatas(bodyData));
		// 可以选填
		paramsMap.put("email", buildEmailConfigs(bodyData));
        paramsMap.put("url", buildUrlConfigs(new String[] {bodyData.getFpqqlsh()}, 
        		isApply ? blueBusiApplyInvoiceCallbackApplyUri
        				: blueBusitransInvoiceCallbackApplyUri));
		paramsMap.put("autoAudit", "true");
		return paramsMap;
	}

	/**
	 * 开票申请审核通过
	 */
//    public static Map<String, Object> issue() {
//        Map<String, Object> paramsMap = new HashMap<String, Object>();
//        paramsMap.put("requestdatas", buildRequestDatas());
//        paramsMap.put("autoAudit", true);
//        return paramsMap;
//    }

	/**
	 * 发票红冲请求服务 电子发票部分红冲
	 */
	public Map<String, Object> red(String orgcode, List<RedInvoiceReqProxyVO> reqVos, boolean isApply) {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("requestdatas", redRequestDatas(orgcode, reqVos));
		String[] fpqqlshs = new String[reqVos.size()];
		for (int i=0; i<reqVos.size(); i++) {
			fpqqlshs[i] = reqVos.get(i).getFpqqlsh();
		}
        paramsMap.put("url", buildUrlConfigs(fpqqlshs, 
        		isApply ? redBusiApplyInvoiceCallbackApplyUri
        				: redBusitransInvoiceCallbackApplyUri));
		paramsMap.put("autoAudit", "true");
		return paramsMap;
	}

	/**
	 * 开票蓝票请求服务--发票拆分
	 */
	public Map<String, Object> insertWithSplit(HxFdcprBusitransApplyInvoiceHeadVO bodyData, boolean isApply) {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("requestdatas", buildRequestDatasSplit(bodyData));
        paramsMap.put("url", buildUrlConfigs(new String[] {bodyData.getFpqqlsh()}, 
        		isApply ? blueBusiApplyInvoiceCallbackApplyUri
        				: blueBusitransInvoiceCallbackApplyUri));
		paramsMap.put("autoAudit", "true");
//        paramsMap.put("email", buildEmailConfigs());
//		paramsMap.put("sms", buildSmsConfigs());
		return paramsMap;
	}

	/**
	 * url回掉配置
	 */
	private String buildUrlConfigs(String[] fpqqlshs, String uri) {
		String blueInvoiceCallbackApplyAbsUrl = invoiceCallbackRootUrl + uri;
		List<Object> datas = new ArrayList<Object>();
		Map<String, Object> data = new HashMap<String, Object>();
		for (int i=0; i< fpqqlshs.length; i++) {
			data.put("fpqqlsh", fpqqlshs[i]);
			data.put("url", blueInvoiceCallbackApplyAbsUrl);
			datas.add(data);
		}
		
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(datas);
	}

	/**
	 * 构造短信发送信息
	 */
	private static String buildSmsConfigs() {
		List<Object> datas = new ArrayList<Object>();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("fpqqlsh", buildFpqqlsh());
		data.put("address", "155****3180");
		datas.add(data);
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(datas);
	}

	/**
	 * 构造email发送信息
	 */
	private static String buildEmailConfigs(HxFdcprBusitransApplyInvoiceHeadVO bodyData) {
		List<Object> datas = new ArrayList<Object>();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("fpqqlsh", bodyData.getFpqqlsh());
		data.put("address", bodyData.getEmail());
		datas.add(data);
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(datas);
	}

	/**
	 * 构造requestdatas
	 */
	private String buildRequestDatas(HxFdcprBusitransApplyInvoiceHeadVO bodyData) {
		List<Object> datas = new ArrayList<Object>();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("FPQQLSH", bodyData.getFpqqlsh());
		data.put("XSF_NSRSBH", bodyData.getXsfNsrsbh());// 91110105MA0084MW37
		data.put("GMF_MC", bodyData.getInvoiceTitle());
		data.put("GMF_NSRSBH", bodyData.getTaxId());
		data.put("ORGCODE", StringUtils.isEmpty(configOrgcode) ? bodyData.getOrgcode() : configOrgcode);
		
		String gmfAddress = StringUtils.hasLength(bodyData.getAddress()) ? bodyData.getAddress() : "";
		String gmfTel = StringUtils.hasLength(bodyData.getTel()) ? bodyData.getTel() : "";
		
		data.put("GMF_DZDH", gmfAddress + " " + gmfTel);

		String gmf_yh = StringUtils.hasLength(bodyData.getAccountBank()) ? bodyData.getAccountBank() : "";
		String gmf_zh = StringUtils.hasLength(bodyData.getAccountNumber()) ? bodyData.getAccountNumber() : "";
		data.put("GMF_YHZH", gmf_yh + " " + gmf_zh);

		data.put("BZ", bodyData.getRemarks());
		data.put("ZDYBZ", getZdybz(bodyData));
//		data.put("ZDYBZ", JSON.toJSON(buildZdybz(bodyData)));
		data.put("FPLX", bodyData.getInvoiceType());
		data.put("JSHJ", bodyData.getTotalAmount());
		
		data.put("SKR", bodyData.getShoukuanPsn());
		data.put("KPR", bodyData.getKaipiaoPsn());
		data.put("FHR", bodyData.getFuhePsn());
		
		data.put("items", buildItems(bodyData.getDetails()));

		datas.add(data);
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(datas);
	}

//	private JSONObject buildZdybz(HxFdcprBusitransApplyInvoiceHeadVO bodyData) {
//		JSONObject result = new JSONObject();
//
//		result.put("busitranspk", bodyData.getBusitransPk());
//		result.put("serviceCenterPk", bodyData.getServiceCenterPk());
//
//		return result;
//	}

	/**
	 * 构造redRequestdatas
	 */
	private String redRequestDatas(String orgcode, List<RedInvoiceReqProxyVO> reqVos) {
		List<Object> datas = new ArrayList<Object>();
		
		reqVos.forEach(reqVO -> {
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("FPQQLSH", reqVO.getFpqqlsh());
			data.put("ORGCODE", StringUtils.isEmpty(configOrgcode) ? orgcode : configOrgcode);
			data.put("fpDm", reqVO.getFpdm());// 91110105MA0084MW37
			data.put("fpHm", reqVO.getFphm());
			datas.add(data);
		});
		
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(datas);
	}

	/**
	 * 拆分
	 *
	 * @return
	 */
	private String buildRequestDatasSplit(HxFdcprBusitransApplyInvoiceHeadVO bodyData) {
		
		
		
		List<Object> datas = new ArrayList<Object>();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("FPQQLSH", bodyData.getFpqqlsh());
		// 测试环境请一定要使用测试纳税人识别号
		data.put("XSF_NSRSBH", bodyData.getXsfNsrsbh());// 91110105MA0084MW37
		data.put("GMF_MC", bodyData.getInvoiceTitle());
		data.put("GMF_NSRSBH", bodyData.getTaxId());
		data.put("ORGCODE", StringUtils.isEmpty(configOrgcode) ? bodyData.getOrgcode() : configOrgcode);
		
		String gmfAddress = bodyData.getAddress();
		String gmfTel = bodyData.getTel();
		data.put("GMF_DZDH",
				StringUtils.hasLength(gmfAddress) ? gmfAddress : "" + (StringUtils.hasLength(gmfTel) ? gmfTel : ""));

		String gmf_yh = bodyData.getAccountBank();
		String gmf_zh = bodyData.getAccountNumber();
		data.put("GMF_YHZH",
				StringUtils.hasLength(gmf_yh) ? gmf_yh : "" + (StringUtils.hasLength(gmf_zh) ? gmf_zh : ""));

		data.put("BZ", bodyData.getRemarks());
		data.put("ZDYBZ", getZdybz(bodyData));
		data.put("FPLX", bodyData.getInvoiceType());
		data.put("JSHJ", bodyData.getTotalAmount());
		
		data.put("SKR", bodyData.getShoukuanPsn());
		data.put("KPR", bodyData.getKaipiaoPsn());
		data.put("FHR", bodyData.getFuhePsn());

		data.put("items", buildItems(bodyData.getDetails()));
		datas.add(data);
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(datas);
	}
	
	
	
	private String getZdybz(HxFdcprBusitransApplyInvoiceHeadVO bodyData) {
		
		
		return bodyData.getBusitransVbillcode();
//		return bodyData.getBusitransPk();
//		StringBuilder builder = new StringBuilder();
//		builder.append("busi").append("_").append(bodyData.getBusitransPk())
//				.append("@")
//				.append("servct").append("_").append(bodyData.getServiceCenterPk())
//				.append("@")
//				.append("psn").append("_").append(bodyData.getInvoicepsn())
//				.append("@")
//				.append("bill").append("_");
//
//		bodyData.getDetails().forEach(detail -> {
//			if ("bill".equals(detail.getDetailType())) {
//				builder.append(detail.getChargeNamePk()).append("/");
//			}
//		});
//		
//		builder.append("@")
//				.append("advance").append("_");
//		bodyData.getDetails().forEach(detail -> {
//			if ("advance".equals(detail.getDetailType())) {
//				builder.append(detail.getChargeNamePk()).append("/");			}
//		});
//		String result = builder.toString();
//		
//		if (result.length() > 200) {
//			zdybzMap.put(bodyData.getFpqqlsh(), result);
//			result = "";
//		}
		
//		return builder.toString();

	}

	/**
	 * 构造request发票明细 实际商品信息应和公司对应的编码信息相同
	 */
	private List<Object> buildItems(List<HxFdcprBusitransApplyInvoiceBodyDetailVO> invoiceItems) {
		List<Object> items = new ArrayList<Object>();
		List<HxFdcprBusitransApplyInvoiceBodyDetailVO> discountList = new ArrayList<HxFdcprBusitransApplyInvoiceBodyDetailVO>();
		for (int i = 0; i < invoiceItems.size(); i++) {
			HxFdcprBusitransApplyInvoiceBodyDetailVO item = invoiceItems.get(i);
			if (item.getNallbrevmny() <= 0) {
				discountList.add(item);
			}
		}

		for (int i = 0; i < invoiceItems.size(); i++) {
			int lineNum = items.size();
			
			HxFdcprBusitransApplyInvoiceBodyDetailVO item = invoiceItems.get(i);
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("XMJSHJ", item.getNallbrevmny());
			data.put("XMMC", item.getTaxName());
			data.put("XMBM", item.getInvoiceTypeNo() == null ? spbm : item.getInvoiceTypeNo());
//			data.put("ZXBM", item.getDetailType() + "" + item.getChargeNamePk());

			data.put("SL", item.getTaxRate());
			data.put("SPBM", item.getInvoiceTypeNo() == null ? spbm : item.getInvoiceTypeNo());
			data.put("HH", lineNum);

			if (item.getNallbrevmny() <= 0) {
				continue;
			}

			// 看当前行能不能作为被折扣行。被折扣行需要满足：
			// 1. 金额大于折扣行
			// 2. 货物或应税服务名称 与 折扣行相同
			if (discountList.isEmpty()) {
				data.put("FPHXZ", "0");
				items.add(data);
				continue;
			}
			
			// || Math.abs(discountList.peek().getNallbrevmny()) > item.getNallbrevmny()
			
			Iterator<HxFdcprBusitransApplyInvoiceBodyDetailVO> iterator = discountList.iterator();
			while (iterator.hasNext()) {
				HxFdcprBusitransApplyInvoiceBodyDetailVO next = iterator.next();
				if (next.getTaxName().equals(item.getTaxName())
						&& Math.abs(item.getNallbrevmny()) > next.getNallbrevmny()) {
					// 需要通过正常行带上折扣行
					// 被折扣行
					data.put("FPHXZ", "2");
					data.put("ZKHHH", lineNum + 1);
					items.add(data);

					// 折扣行
					Map<String, Object> discountData = new HashMap<String, Object>();
					discountData.put("XMJSHJ", next.getNallbrevmny());
					discountData.put("XMMC", item.getTaxName());
					discountData.put("XMBM", spbm);
					discountData.put("SL", item.getTaxRate());
					discountData.put("SPBM", spbm);
					discountData.put("HH", lineNum + 1);
					discountData.put("FPHXZ", "1");
					items.add(discountData);
					
					iterator.remove();
					break;
				}
			}

			

			

		}

		return items;
	}

	/**
	 * 获取发票请求流水号 长度不超过20位，长度在1到20位的字母和数字组合，不可以重复的，不要包含window系统文件名限制的特殊字符
	 *
	 * @return 发票请求流水号
	 */
	private static String buildFpqqlsh() {
		return "svc20210628141034422";
	}

	/**
	 * 发票作废Requestdatas参数
	 */
	private static String buildInvalidRequestdatas(String fpHm, String fmDm) {
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("fpHm", fpHm);
		data.put("fpDm", fmDm);
		GsonBuilder builder = new GsonBuilder();
		return builder.create().toJson(data);
	}

	public static Map<String, Object> save() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		// 发票代码
		paramsMap.put("lyid", "1");
		// 发票号码
		paramsMap.put("djqqlsh", "23770399");
		paramsMap.put("orgCode", "20160914001");
		paramsMap.put("pageNum", "1");
		paramsMap.put("orgSize", "20160914001");
		paramsMap.put("GMF_MC", "广州佰仕德材料科技有限公司");
		paramsMap.put("GMF_NSRSBH", "91440101MA5CR3FU35");
		paramsMap.put("GMF_DZDH", "广州市花都区红棉大道北16号4楼4B07室 020-61796191");
		paramsMap.put("GMF_YHZH", "中国农业银行股份有限公司广州花都名门支行 44087001040011474");

		paramsMap.put("zdrq", "2020-09-09");
		paramsMap.put("invoiceWillBs", buildWillbs());
		return paramsMap;
	}

	private static Object buildWillbs() {

		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("XMMC", "硅胶5299B");
		paramsMap.put("XMBM", "202020012");
		paramsMap.put("GGXH", "25kg/桶");
		paramsMap.put("DW", "千克");
		paramsMap.put("XMSL", 2);
		paramsMap.put("XMJSHJ", 40);
		paramsMap.put("hh", "1");
		paramsMap.put("SPBM", "1070213070000000000");
		paramsMap.put("SL", 0.16);
		return paramsMap;
	}

	/**
	 * 未开票记录变更查询 报错
	 */
	public static Map<String, Object> change() {
		Map<String, Object> paramsMap = new HashMap<String, Object>();

		// 发票号码
		paramsMap.put("beginTime", "2019-10-24 16:31:15");
		paramsMap.put("endTime", "2021-01-01 16:31:15");
//        paramsMap.put("orgCode", "20160914001");
		paramsMap.put("pageNum", 2);
		paramsMap.put("pageSize", 15);

		return paramsMap;
	}
}
